// Copyright (C) 1999-2000 Id Software, Inc.
//
// cg_consolecmds.c -- text commands typed in at the local console, or
// executed by a key binding

#include "cg_local.h"
#include "cgame_BOTS.h"

// BEGIN bots - tbp
// Quick test
void BOTS_Huhu_f(void) {
	trace_t		trace;
	vec3_t		start, end;


	// targetNum = CG_CrosshairPlayer();
	cg.iPseudoPowerupTime[cg.predictedPlayerState.clientNum] = cg.time;

	VectorCopy( cg.refdef.vieworg, start );
	VectorMA( start, 500, cg.refdef.viewaxis[0], end );
	CG_Trace( &trace, start, vec3_origin, vec3_origin, end, cg.snap->ps.clientNum, MASK_SHOT );

	switch (atoi(CG_Argv(1))) {
	case 1:
		BOTS_Effect1(trace.endpos);
		break;
	case 2:
		BOTS_Effect2(trace.endpos);
		break;
	case 3:
		BOTS_Effect3(trace.endpos);
		break;
	case 4:
		BOTS_Effect4(trace.endpos);
		break;
	case 5:
		BOTS_Effect5(trace.endpos);
		break;
	case 0:
	default:
		CG_Printf("Give me an argument, foo!\n");
	}
}
// END bots - tbp


void CG_TargetCommand_f( void ) {
	int		targetNum;
	char	test[4];

	targetNum = CG_CrosshairPlayer();
	if (!targetNum ) {
		return;
	}

	trap_Argv( 1, test, 4 );
	trap_SendConsoleCommand( va( "gc %i %i", targetNum, atoi( test ) ) );
}



/*
=================
CG_SizeUp_f

Keybinding command
=================
*/
static void CG_SizeUp_f (void) {
	trap_Cvar_Set("cg_viewsize", va("%i",(int)(cg_viewsize.integer+10)));
}


/*
=================
CG_SizeDown_f

Keybinding command
=================
*/
static void CG_SizeDown_f (void) {
	trap_Cvar_Set("cg_viewsize", va("%i",(int)(cg_viewsize.integer-10)));
}


/*
=============
CG_Viewpos_f

Debugging command to print the current position
=============
*/
static void CG_Viewpos_f (void) {
	CG_Printf ("(%i %i %i) : %i\n", (int)cg.refdef.vieworg[0],
		(int)cg.refdef.vieworg[1], (int)cg.refdef.vieworg[2], 
		(int)cg.refdefViewAngles[YAW]);
}


static void CG_ScoresDown_f( void ) {
	if ( cg.scoresRequestTime + 2000 < cg.time ) {
		// the scores are more than two seconds out of data,
		// so request new ones
		cg.scoresRequestTime = cg.time;
		trap_SendClientCommand( "score" );

		// leave the current scores up if they were already
		// displayed, but if this is the first hit, clear them out
		if ( !cg.showScores ) {
			cg.showScores = qtrue;
			cg.numScores = 0;
		}
	} else {
		// show the cached contents even if they just pressed if it
		// is within two seconds
		cg.showScores = qtrue;
	}
}

static void CG_ScoresUp_f( void ) {
	cg.showScores = qfalse;
	cg.scoreFadeTime = cg.time;
}

static void CG_TellTarget_f( void ) {
	int		clientNum;
	char	command[128];
	char	message[128];

	clientNum = CG_CrosshairPlayer();
	if ( clientNum == -1 ) {
		return;
	}

	trap_Args( message, 128 );
	Com_sprintf( command, 128, "tell %i %s", clientNum, message );
	trap_SendClientCommand( command );
}

static void CG_TellAttacker_f( void ) {
	int		clientNum;
	char	command[128];
	char	message[128];

	clientNum = CG_LastAttacker();
	if ( clientNum == -1 ) {
		return;
	}

	trap_Args( message, 128 );
	Com_sprintf( command, 128, "tell %i %s", clientNum, message );
	trap_SendClientCommand( command );
}


typedef struct {
	char	*cmd;
	void	(*function)(void);
} consoleCommand_t;

static consoleCommand_t	commands[] = {
	{ "testgun", CG_TestGun_f },
	{ "testmodel", CG_TestModel_f },
	{ "nextframe", CG_TestModelNextFrame_f },
	{ "prevframe", CG_TestModelPrevFrame_f },
	{ "nextskin", CG_TestModelNextSkin_f },
	{ "prevskin", CG_TestModelPrevSkin_f },
	{ "viewpos", CG_Viewpos_f },
	{ "+scores", CG_ScoresDown_f },
	{ "-scores", CG_ScoresUp_f },
	{ "+zoom", CG_ZoomDown_f },
	{ "-zoom", CG_ZoomUp_f },
	{ "sizeup", CG_SizeUp_f },
	{ "sizedown", CG_SizeDown_f },
	{ "weapnext", CG_NextWeapon_f },
	{ "weapprev", CG_PrevWeapon_f },
	{ "weapon", CG_Weapon_f },
	{ "tell_target", CG_TellTarget_f },
	{ "tell_attacker", CG_TellAttacker_f },
	{ "tcmd", CG_TargetCommand_f },
	{ "loaddefered", CG_LoadDeferredPlayers },	// spelled wrong, but not changing for demo...
	{ "+gren", BOTS_plusgren },
	{ "-gren", BOTS_minusgren },
	{ "+alias", CG_AliasDown_f },
    { "-alias", CG_AliasUp_f },
	{ "+blink", BOTS_plusblink },
	{ "-blink", BOTS_minusblink },
	{ "radio", BOTS_Radio_f },
	{ "radiotog", BOTS_Radiotog_f },
	{ "radiolist", BOTS_Radiolist_f },
	{ "datacount", BOTS_Datacount_f },
	{ "huhu", BOTS_Huhu_f }
};


/*
=================
CG_ConsoleCommand

The string has been tokenized and can be retrieved with
Cmd_Argc() / Cmd_Argv()
=================
*/

void BOTS_FOO();

qboolean CG_ConsoleCommand( void ) {
	const char	*cmd;
	int		i;
	static char *sIllegalCommands[] = { "callvote" }; // kinda empty right now :)

	cmd = CG_Argv(0);

// BEGIN bots - tbp
	// Shunt some commands that may fux0r the game and print out a stupid message.
	for ( i = 0 ; i < sizeof(sIllegalCommands)/sizeof(sIllegalCommands[0]); i++ ) {
		if (!Q_stricmp(cmd, sIllegalCommands[i])) {
			CG_Printf("ILLEGAL COMMAND.\nPLEASE STAND STILL UNTIL POLICE FORCES ARRIVE.\n");
			return qtrue; // To stop further parsing
		}
	}
// END bots - tbp

	for ( i = 0 ; i < sizeof( commands ) / sizeof( commands[0] ) ; i++ ) {
		if ( !Q_stricmp( cmd, commands[i].cmd ) ) {
			commands[i].function();
			return qtrue;
		}
	}

// BEGIN bots - nits
	//return BOTS_CG_ConsoleCommand(cmd);
// END bots - nits
	return qfalse;
}


/*
=================
CG_InitConsoleCommands

Let the client system know about all of our commands
so it can perform tab completion
=================
*/
void CG_InitConsoleCommands( void ) {
	int		i;

	for ( i = 0 ; i < sizeof( commands ) / sizeof( commands[0] ) ; i++ ) {
		trap_AddCommand( commands[i].cmd );
	}

	//
	// the game server will interpret these commands, which will be automatically
	// forwarded to the server after they are not recognized locally
	//
	trap_AddCommand ("kill");
	trap_AddCommand ("say");
	trap_AddCommand ("say_team");
	trap_AddCommand ("give");
	trap_AddCommand ("god");
	trap_AddCommand ("notarget");
	trap_AddCommand ("noclip");
	trap_AddCommand ("team");
	trap_AddCommand ("follow");
	trap_AddCommand ("levelshot");
	trap_AddCommand ("addbot");
	trap_AddCommand ("setviewpos");
	trap_AddCommand ("vote");
	trap_AddCommand ("callvote");
	trap_AddCommand ("loaddefered");	// spelled wrong, but not changing for demo

// BEGIN bots - nits
	trap_AddCommand ("split");
	trap_AddCommand ("dettog");
// END bots - nits
// BEGIN bots - tbp
	// Why not?
	trap_AddCommand ("mapvote");
	trap_AddCommand ("mute");
	trap_AddCommand ("unmute");
	trap_AddCommand ("rejoin");
	trap_AddCommand ("create");
	trap_AddCommand ("genresearch");
	trap_AddCommand ("promote");
	trap_AddCommand ("demote");
	trap_AddCommand ("video");

	trap_AddCommand ("warcry");
	trap_AddCommand ("repel");

	// Referee
	trap_AddCommand ("ref_status");
	trap_AddCommand ("ref_freeze");
	trap_AddCommand ("ref_kick");
	trap_AddCommand ("ref_map");
	trap_AddCommand ("ref_mute");
	trap_AddCommand ("ref_unmute");
	trap_AddCommand ("ref_matchmode");
	trap_AddCommand ("ref_classes");

	// Classes
	trap_AddCommand ("captain");
	trap_AddCommand ("bodyguard");
	trap_AddCommand ("sniper");
	trap_AddCommand ("soldier");
	trap_AddCommand ("berzerker");
	trap_AddCommand ("infiltrator");
	trap_AddCommand ("kamikazee");
	trap_AddCommand ("scientist");
	trap_AddCommand ("nurse");
// END bots - tbp
}
